package www.wmx.com.xssc.util;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import www.wmx.com.xssc.domain.doc.fj.RbtScfjMb;
import www.wmx.com.xssc.domain.doc.fj.ZtComUploadFile;
import www.wmx.com.xssc.domain.doc.fj.ZtComUploadFileOrigin;
import www.wmx.com.xssc.domain.doc.jcyjj.RbtKjjlJcyjjFjxx;
import www.wmx.com.xssc.domain.doc.jsfmj.RbtKjjlJsfmjFjxx;
import www.wmx.com.xssc.domain.doc.kjjbj.RbtKjjlKjjbjFjxx;
import www.wmx.com.xssc.domain.mb.RbtKjjlMbJcyjRank;
import www.wmx.com.xssc.domain.mb.RbtKjjlMbTy;
import www.wmx.com.xssc.domain.vo.WcryShortXM;
import www.wmx.com.xssc.domain.vo.extract.BaseMatchResult;
import www.wmx.com.xssc.domain.vo.extract.ExtractZZ;
import www.wmx.com.xssc.domain.vo.extract.request.ZZRequest;
import www.wmx.com.xssc.domain.vo.request.RequestPicture;
import www.wmx.com.xssc.domain.vo.response.ResponsePicture;
import www.wmx.com.xssc.service.fj.IRbtScfjMbService;
import www.wmx.com.xssc.service.fj.IZtComUploadFileOriginService;
import www.wmx.com.xssc.service.fj.IZtComUploadFileService;
import www.wmx.com.xssc.service.jcyjj.IRbtKjjlJcyjjFjxxService;
import www.wmx.com.xssc.service.jcyjj.IRbtKjjlJcyjjJbxxService;
import www.wmx.com.xssc.service.jsfmj.IRbtKjjlJsfmjFjxxService;
import www.wmx.com.xssc.service.kjjbj.IRbtKjjlKjjbjFjxxService;
import www.wmx.com.xssc.util.common.MbReadUtil;
import www.wmx.com.xssc.util.common.NameConvertUtil;
import www.wmx.com.xssc.util.common.WcrReadUtil;
import www.wmx.com.xssc.util.enumUtil.CgType;
import www.wmx.com.xssc.util.enumUtil.CgjlType;
import www.wmx.com.xssc.util.pdf.PDF;
import www.wmx.com.xssc.util.tptq.ImageExtractionUtil;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static www.wmx.com.xssc.xm.Similarity.pinyinSimilarity;

/**
 * @author Zhenyao.Diao
 * @create 2024/11/4 10:44
 * @description 著作处理工具
 * 著作的图片处理过程和论文的处理工具是一致的
 */

@Slf4j
@Data
@Component
public class ZZProcessUtil {

    /**
     * 列举类型所有的成果奖励的基本信息业务类：
     */
    @Resource(description = "基础研究奖的基本信息：")
    private IRbtKjjlJcyjjJbxxService jcyjjJbxxService;

    @Resource(description = "通用模板，作者排名信息的获取")
    private MbReadUtil mbReadUtil;
    /**
     * 所有当前年度的项目中涉及的研究人员和项目的信息：
     */
    @Resource
    private WcrReadUtil wcrReadUtil;

    @Resource(description = "附件的类型枚举")
    private IRbtScfjMbService scfjMbService;
    //专著附件的所有的类型和名称：
    List<RbtScfjMb> scfjJcyjjZZMbList;
    List<RbtScfjMb> scfjKjjbjjZZMbList;
    List<RbtScfjMb> scfjJsfmjZZMbList;
    @Resource(description = "基础研究附件信息")
    private IRbtKjjlJcyjjFjxxService jcyjjFjxxService;
    @Resource(description = "技术发明奖附件信息")
    private IRbtKjjlJsfmjFjxxService jsfmjFjxxService;
    @Resource(description = "科技进步奖附件信息")
    private IRbtKjjlKjjbjFjxxService kjjbjFjxxService;

    @Resource(description = "专著图片提取工具")
    private ImageExtractionUtil imageExtractionUtil;

    @Resource(description = "用于获取附件的地址信息")
    private IZtComUploadFileService uploadFileService;
    @Resource(description = "同上用于获取附件的地址信息")
    private IZtComUploadFileOriginService uploadFileOriginService;

    private static final Pattern pattern = Pattern.compile("[\\u4e00-\\u9fa5]+");
    private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd");


    // 作者排名：
    private RbtKjjlMbJcyjRank kjjlMbJcyjRank;
    //contains:   0、1、2
    private RbtKjjlMbTy rbtKjjlMbTyZZ;

    private String basePath;

    /**
     * 获取各个奖项的所有的附件类型
     */
    public void init() {
        this.mbReadUtil.init();
        this.scfjJcyjjZZMbList = scfjMbService.lambdaQuery()
                .eq(RbtScfjMb::getYwlx, "基础研究奖")
                .eq(RbtScfjMb::getWjlx, "专著").list();
        this.scfjKjjbjjZZMbList = scfjMbService.lambdaQuery()
                .eq(RbtScfjMb::getYwlx, "科技进步奖")
                .eq(RbtScfjMb::getWjlx, "专著").list();
        this.scfjJsfmjZZMbList = scfjMbService.lambdaQuery()
                .eq(RbtScfjMb::getYwlx, "技术发明奖")
                .eq(RbtScfjMb::getWjlx, "专著").list();
        this.kjjlMbJcyjRank = this.mbReadUtil.getKjjlMbJcyjRank();
        List<RbtKjjlMbTy> kjjlMbTyList = this.mbReadUtil.getKjjlMbTyList();
        for (RbtKjjlMbTy mbTy : kjjlMbTyList) {
            if (mbTy.getId().equals(CgType.ZZ.getCode())) {
                this.rbtKjjlMbTyZZ = mbTy;
                break;
            }
        }

        try {
            Properties properties = new Properties();
            // 读取my.properties配置文件到输入流中
            InputStream inputStream = PDF.class.getResourceAsStream("/config.properties");
            // 从输入流中加载属性列表
            properties.load(inputStream);
            this.basePath = properties.getProperty("file.upload.path");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    /**
     * 获取专著的存储地址
     *
     * @param zzRequest
     * @return
     */
    public String getZZPath(ZZRequest zzRequest) {
        String path = null;
        String FJID = null;
        if (zzRequest.getCgjlType() == CgjlType.JCYJJ.getCode()) {
            RbtKjjlJcyjjFjxx jcyjjFjxx = jcyjjFjxxService.lambdaQuery()
                    .eq(RbtKjjlJcyjjFjxx::getKjjlJcyjjId, zzRequest.getJbxxID())
                    .eq(RbtKjjlJcyjjFjxx::getWjlx, "专著")
                    .eq(RbtKjjlJcyjjFjxx::getWjmc, "专著题目作者裁剪")
                    .one();
            if (jcyjjFjxx == null) return null;
            FJID = jcyjjFjxx.getFjId();
            ZtComUploadFile uploadFile = uploadFileService.lambdaQuery()
                    .eq(ZtComUploadFile::getId, FJID)
                    .one();
            if (uploadFile == null) return null;
            ZtComUploadFileOrigin uploadFileOrigin = uploadFileOriginService.lambdaQuery()
                    .eq(ZtComUploadFileOrigin::getId, uploadFile.getFileMd5())
                    .one();
            if (uploadFileOrigin == null || uploadFileOrigin.getFilePath().isEmpty()) {
                return null;
            }
            path = uploadFileOrigin.getFilePath();
        } else if (zzRequest.getCgjlType() == CgjlType.JSFMJ.getCode()) {
            RbtKjjlJsfmjFjxx jsfmjFjxx = jsfmjFjxxService.lambdaQuery()
                    .eq(RbtKjjlJsfmjFjxx::getKjjlJsfmjId, zzRequest.getJbxxID())
                    .eq(RbtKjjlJsfmjFjxx::getWjlx, "专著")
                    .eq(RbtKjjlJsfmjFjxx::getWjmc, "专著题目作者裁剪")
                    .one();
            if (jsfmjFjxx == null) return null;
            FJID = jsfmjFjxx.getFjId();
            ZtComUploadFile uploadFile = uploadFileService.lambdaQuery()
                    .eq(ZtComUploadFile::getId, FJID)
                    .one();
            if (uploadFile == null) return null;
            ZtComUploadFileOrigin uploadFileOrigin = uploadFileOriginService.lambdaQuery()
                    .eq(ZtComUploadFileOrigin::getId, uploadFile.getFileMd5())
                    .one();
            if (uploadFileOrigin == null || uploadFileOrigin.getFilePath().isEmpty()) {
                return null;
            }
            path = uploadFileOrigin.getFilePath();
        } else if (zzRequest.getCgjlType() == CgjlType.KJJBJ.getCode()) {
            RbtKjjlKjjbjFjxx kjjbjFjxx = kjjbjFjxxService.lambdaQuery()
                    .eq(RbtKjjlKjjbjFjxx::getKjjlKjjbjId, zzRequest.getJbxxID())
                    .eq(RbtKjjlKjjbjFjxx::getWjlx, "专著")
                    .eq(RbtKjjlKjjbjFjxx::getWjmc, "专著题目作者裁剪")
                    .one();
            if (kjjbjFjxx == null) return null;
            FJID = kjjbjFjxx.getFjId();
            ZtComUploadFile uploadFile = uploadFileService.lambdaQuery()
                    .eq(ZtComUploadFile::getId, FJID)
                    .one();
            if (uploadFile == null) return null;
            ZtComUploadFileOrigin uploadFileOrigin = uploadFileOriginService.lambdaQuery()
                    .eq(ZtComUploadFileOrigin::getId, uploadFile.getFileMd5())
                    .one();
            if (uploadFileOrigin == null || uploadFileOrigin.getFilePath().isEmpty()) {
                return null;
            }
            path = uploadFileOrigin.getFilePath();
        }
        if(!ImageExtractionUtil.isImageFile(path,basePath)){
            return null;
        }
        return this.basePath + path;
    }

    public ResponsePicture extractPicture(ZZRequest zzRequest) {
        RequestPicture requestPicture = new RequestPicture();
        requestPicture.setFilePath(zzRequest.getFilePath());
        ResponsePicture responsePicture = null;
        try {
            responsePicture = imageExtractionUtil.sendFormPost(requestPicture);
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return responsePicture;
    }

    public BaseMatchResult matchProcess(ZZRequest zzRequest) {
        BaseMatchResult result = new BaseMatchResult();
        String zzPath = getZZPath(zzRequest);
        zzRequest.setFilePath(zzPath);
//        zzRequest.setFilePath("/home/user/workspace/test3.png");//测试用路径
//        zzRequest.setFilePath("/root/OCR_Application/ocr_test_images/test3.png");//测试用路径
        List<String> failReason = new ArrayList<>();
        String zzmcEnroll = zzRequest.getZzmc();
        int type = 0; //默认采用的中文专著证书：
        if (containsNoChinese(zzmcEnroll)) type = 1;
        List<String> zzzzList = null;
        if(zzPath!=null) {
            ResponsePicture responsePicture = extractPicture(zzRequest);
            if(responsePicture!= null) {
                zzRequest.setPlainText(responsePicture.getData());
            }
            //这是从论文中提取出来的内容：
            if(zzRequest.getPlainText()!=null) {
                ExtractZZ extractZZ = processZZ(zzRequest, type);
                if(extractZZ!=null && extractZZ.getZz()!=null && !extractZZ.getZz().isEmpty()) {
                    zzzzList = extractZZ.getZz();
                }
            }
        }else {
            failReason.add("专著题目作者裁剪不存在请重新上传");
        }
        zzRequest.setAuthorRankLimit(this.mbReadUtil.getKjjlMbJcyjRank().getZzpm());
        LocalDateTime xmBeginTimeEnroll = zzRequest.getXmBeginTime();
        LocalDateTime xmEndTimeEnroll = zzRequest.getXmEndTime();
        //基础研究奖的作者排名限制：
        int authorRankLimit = kjjlMbJcyjRank.getZzpm();
        boolean wcrMatchResult  = false;
        //1.专著完成人一员的审查
        if(zzPath!=null && zzzzList!=null && !zzzzList.isEmpty()) {
            wcrMatchResult = wcrMatch(zzzzList, type, zzRequest);
        }
        //2.时间的审查
        boolean dateMatchResult = dateMatch(xmBeginTimeEnroll, xmEndTimeEnroll, zzRequest);
        //3.如果是基础研奖还需要对作者排名进行校验：
        boolean rankLimitMatchResult = false;
        if (zzPath!=null && zzzzList!=null && !zzzzList.isEmpty() && zzRequest.getCgjlType() == CgjlType.JCYJJ.getCode()) {
            rankLimitMatchResult = wcrRankLimitMatch(zzRequest, zzzzList, type, authorRankLimit);
        }
        //4.专著附件的校验：
        List<String> failReasonFJ = FJCheck(zzRequest);

        if (!dateMatchResult) {
            result.setSuccess(false);
            failReason.add("时间不匹配： " + zzRequest.getFbsj().format(DATE_FORMAT) + " 论文发表时间并未在项目起始时间段内");
        }
        if (zzPath!=null && zzzzList!=null && !zzzzList.isEmpty() && !wcrMatchResult) {
            result.setSuccess(false);
            failReason.add("完成人不匹配： " + "项目完成人中的任意一位" + " 并非是专著完成人中的一员");
        }
        if (zzPath!=null && zzzzList!=null && !zzzzList.isEmpty() && zzRequest.getCgjlType() == CgjlType.JCYJJ.getCode() && !rankLimitMatchResult) {
            result.setSuccess(false);
            failReason.add("专著作者排名不匹配： " + "项目完成人中的任意一位" + " 并非是专著的前 " + authorRankLimit + "作者");
        }
        if (failReasonFJ != null && failReasonFJ.size() > 0) {
            failReason.addAll(failReasonFJ);
        }
        result.setFailReason(failReason);
        return result;
    }

    /**
     * 专著的附件的审查：
     */
    public List<String> FJCheck(ZZRequest zzRequest) {
        List<String> failReason = new ArrayList<>();
        if (zzRequest.getCgjlType() == CgjlType.JCYJJ.getCode()) {
            for (RbtScfjMb scfjMb : scfjJcyjjZZMbList) {
                List<RbtKjjlJcyjjFjxx> fjxx = jcyjjFjxxService.lambdaQuery()
                        .eq(RbtKjjlJcyjjFjxx::getKjjlJcyjjId, zzRequest.getJbxxID())
                        .eq(RbtKjjlJcyjjFjxx::getWjmc, scfjMb.getWjmc())
                        .eq(RbtKjjlJcyjjFjxx::getWjlx, "专著")
                        .list();
                if (fjxx == null || fjxx.isEmpty()) {
                    failReason.add("专著缺少附件:  " + scfjMb.getWjmc() + " ");
                }
            }
        } else if (zzRequest.getCgjlType() == CgjlType.JSFMJ.getCode()) {
            for (RbtScfjMb scfjMb : scfjJsfmjZZMbList) {
                List<RbtKjjlJsfmjFjxx> fjxx = jsfmjFjxxService.lambdaQuery()
                        .eq(RbtKjjlJsfmjFjxx::getKjjlJsfmjId, zzRequest.getJbxxID())
                        .eq(RbtKjjlJsfmjFjxx::getWjmc, scfjMb.getWjmc())
                        .eq(RbtKjjlJsfmjFjxx::getWjlx, "专著")
                        .list();
                if (fjxx == null || fjxx.isEmpty()) {
                    failReason.add("专著缺少附件:  " + scfjMb.getWjmc() + " ");
                }
            }
        } else if (zzRequest.getCgjlType() == CgjlType.KJJBJ.getCode()) {
            for (RbtScfjMb scfjMb : scfjKjjbjjZZMbList) {
                List<RbtKjjlKjjbjFjxx> fjxx = kjjbjFjxxService.lambdaQuery()
                        .eq(RbtKjjlKjjbjFjxx::getKjjlKjjbjId, zzRequest.getJbxxID())
                        .eq(RbtKjjlKjjbjFjxx::getWjmc, scfjMb.getWjmc())
                        .eq(RbtKjjlKjjbjFjxx::getWjlx, "专著")
                        .list();
                if (fjxx == null || fjxx.isEmpty()) {
                    failReason.add("专著缺少附件:  " + scfjMb.getWjmc() + " ");
                }
            }
        }
        return failReason;
    }

    private boolean wcrRankLimitMatch(ZZRequest zzRequest, List<String> zzzzList, int type, int authorRankLimit) {
        //项目已经登记的项目参与人员：
        List<WcryShortXM> wcryShortXMList = wcrReadUtil.getWcryFilterByTypeAndId(zzRequest.getCgjlType(), zzRequest.getJbxxID());
        if (wcryShortXMList == null || wcryShortXMList.isEmpty()) {
            return false;
        }
        boolean flag = false;
        for (int i = 0; i < 3; i++) {
            String name = zzzzList.get(i);
            name = name.replaceAll(" ", "");
            String pinyinName = NameConvertUtil.convertToPinyin(name);
            for (WcryShortXM wcryShortXM : wcryShortXMList) {
                String enrollName = NameConvertUtil.convertToPinyin(wcryShortXM.getXm().replaceAll(" ", ""));
                double similarity = pinyinSimilarity(pinyinName, enrollName);
                if (pinyinName.equals(enrollName) || similarity >= 0.8) {
                    flag = true;
                    break;
                }
            }
        }
        return flag;
    }

    //论文完成时间的审查：
    public boolean dateMatch(LocalDateTime begin, LocalDateTime end, ZZRequest zzRequest) {
        LocalDateTime fbsj = zzRequest.getFbsj().atStartOfDay();
        return fbsj.isAfter(begin) && fbsj.isBefore(end);
    }

    /**
     * @param zzzzList  从软著图片提取出来的作者信息：
     * @param type
     * @param zzRequest
     * @return
     */
    private boolean wcrMatch(List<String> zzzzList, int type, ZZRequest zzRequest) {
        //项目中已经登记的完成人员信息：
        List<WcryShortXM> wcryShortXMList = wcrReadUtil.getWcryFilterByTypeAndId(zzRequest.getCgjlType(), zzRequest.getJbxxID());
        if (wcryShortXMList == null || wcryShortXMList.isEmpty()) {
            return false;
        }
        for (String name : zzzzList) {
            name = name.replaceAll(" ", "");
            String pinyinName = NameConvertUtil.convertToPinyin(name);
            for (WcryShortXM wcryShortXM : wcryShortXMList) {
                String enrollName = NameConvertUtil.convertToPinyin(wcryShortXM.getXm().replaceAll(" ", ""));
                double similarity = pinyinSimilarity(pinyinName, enrollName);
                if (pinyinName.equals(enrollName) || similarity >= 0.8) {
                    return true;
                }
            }
        }
        return false;
    }

    public ExtractZZ processZZ(ZZRequest zzRequest, Integer type) {
        if (type.equals(0)) {
            return processChinese(zzRequest);
        } else {
            return processEnglish(zzRequest);
        }
    }

    public ExtractZZ processChinese(ZZRequest zzRequest) {
        ExtractZZ response = new ExtractZZ();
        String zzsmcOrigin = zzRequest.getZzmc();
        String request = zzRequest.getPlainText();
        String twoCharStr = zzsmcOrigin;
        String wcrStr = null;
        if(zzsmcOrigin.length()>2) {
            twoCharStr = zzsmcOrigin.substring(zzsmcOrigin.length() - 2);
        }
        int wcrIndexBegin = -1;
        if(request.indexOf(twoCharStr)!=-1) {
            wcrIndexBegin = request.indexOf(twoCharStr) + 2;
        }
        if(wcrIndexBegin!=-1 && wcrIndexBegin<request.length()){
            wcrStr = request.substring(wcrIndexBegin);
        }
        String noNewLines = wcrStr.replaceAll("[\\r\\n]+", " ");
        // 然后，将多个连续的空格替换为一个空格
        wcrStr = noNewLines.replaceAll("\\s+", " ");
        String[] wcrNameSplit = wcrStr.split("[,，、]+");
        List<String> zzwcrList = new ArrayList<>();
        for (String sName : wcrNameSplit) {
            // 使用正则表达式匹配所有汉字
            // 使用Pattern和Matcher类来查找所有匹配的汉字
            Matcher matcher = pattern.matcher(sName);
            // 创建一个StringBuilder来存储所有找到的汉字
            StringBuilder chineseCharacters = new StringBuilder();
            while (matcher.find()) {
                // 将找到的汉字添加到StringBuilder中
                chineseCharacters.append(matcher.group()).append(" ");
            }
            // 去除最后一个多余的空格（如果有的话）
            if (chineseCharacters.length() > 0 && chineseCharacters.charAt(chineseCharacters.length() - 1) == ' ') {
                chineseCharacters.deleteCharAt(chineseCharacters.length() - 1);
            }
            zzwcrList.add(chineseCharacters.toString());
        }
//        zzwcrList.forEach(System.out::println);
        response.setZzmc(zzsmcOrigin);
        response.setType(0);
        response.setZz(zzwcrList);
        return response;
    }

    public ExtractZZ processEnglish(ZZRequest zzRequest) {
        return null;
    }

    // 判断字符串是否不含有中文
    public boolean containsNoChinese(String input) {
        if (input == null || input.isEmpty()) {
            return true; // 空字符串不包含中文
        }

        for (char c : input.toCharArray()) {
            // 检查字符是否在中文范围内
            if (isChineseCharacter(c)) {
                return false; // 一旦发现中文字符，返回false
            }
        }
        return true; // 遍历完所有字符，未发现中文字符，返回true
    }

    // 判断单个字符是否是中文字符
    private boolean isChineseCharacter(char c) {
        // 基本区
        if (c >= '\u4E00' && c <= '\u9FFF') {
            return true;
        }
        return false;
    }


}
